package com.sun.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.sun.commons.utils.PropertiesConfig;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.DefaultLoginPageConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import java.util.Map;
import java.util.Optional;

/**
 * MP自动填充Handler
 *
 * @Author whsunchunbo@qq.com
 * @CreateTime 2025/9/8 21:20
 */
@Configuration
@EnableWebSecurity
@EnableMethodSecurity(securedEnabled = true) // 开启方法级别的权限控制
@RequiredArgsConstructor
public class SecruityConfig {
    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private JwtFilter jwtFilter;
    @Autowired
    private PropertiesConfig propertiesConfig;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.removeConfigurer(DefaultLoginPageConfigurer.class);
        return http.csrf(csrf -> csrf.disable())
                .authorizeHttpRequests((authorizeHttpRequests) -> {
                            //注意这里，先声明的具有高优先级。

                            authorizeHttpRequests
                                    .requestMatchers(propertiesConfig.getIgnoreUrls().toArray(String[]::new)).permitAll()
//                                .requestMatchers("/wechat/**").permitAll()
                                    .anyRequest().authenticated();

                        }

                )
                .cors(cors -> {
                })
                .httpBasic(basic -> basic.disable())
                .formLogin(formLogin -> formLogin.disable())
                .anonymous(anonymous -> anonymous.disable())
                .exceptionHandling(errorHandling -> errorHandling.accessDeniedHandler(accessDeniedHandler()))
                .sessionManagement(sessionManagement -> sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class)
                .build();


    }

//    @Bean
//    public WebSecurityCustomizer  webSecurityCustomizer() {
//        return (web) -> web.ignoring()
//                .requestMatchers("/swagger-ui/**", "/swagger-ui/**", "/api-docs/**", "/v3/**")
//                .requestMatchers(PathRequest.toStaticResources().atCommonLocations());
//    }

    @Bean
    public AccessDeniedHandler accessDeniedHandler() {
        return (request, response, accessDeniedException) -> {
            response.setCharacterEncoding("UTF-8");
            Optional<Object> tokenIssue = Optional.ofNullable(request.getAttribute("TOKEN_ISSUE"));
            if (tokenIssue.isPresent()) {
                response.getWriter().println(objectMapper.writeValueAsString(Map.of("message", tokenIssue.get())));
                response.setStatus(HttpStatus.UNAUTHORIZED.value());
            } else {
                response.getWriter().println(objectMapper.writeValueAsString(Map.of("message", "您不具有相关权限")));
                response.setStatus(HttpStatus.FORBIDDEN.value());
            }

        };

    }


    // Password Encoding
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
